package cc.wanforme.text2class.handler;

import cc.wanforme.text2class.entity.AnalysisConfig;
import cc.wanforme.text2class.entity.BeanField;

import java.util.ArrayList;
import java.util.List;

public abstract class BaseDataAnalysis {

    public static boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }

    /** 文本解析成 BeanDef。
     * @param text 原始文本
     * @param config 运行过程中的一些基础信息和配置
     * */
    public List<BeanField> analysis (String text, AnalysisConfig config) {
        List<String> lines = toLines(text, config);

        // 1. 拆分成一条一条的格式化字符串
        List<BeanField> list = new ArrayList<>(lines.size());
        for (String line : lines) {
            BeanField bf = new BeanField();
            list.add(bf);

            // 2. 每条字符串的前置处理
            String rawLine = beforeAnalysis(line.trim(), config);
            bf.setRawLine(rawLine);
            if (rawLine.isEmpty()) {
                continue;
            }

            // 3. 把一条字符串拆分成元素数组。 样例: id long 主键No
            List<String> items = cutElements(rawLine, config);
            if (items.size() <= 1) {
                break;
            }

            // 4. 属性名 id
            String name = getName(rawLine, items, config);
            bf.setName(name);
            // 5. 数据类型
            String type = getType(rawLine, items, config);
            bf.setType(type);
            // 6. 注释说明
            String desc = getDesc(rawLine, items, config);
            bf.setDesc(desc);

            // 7. 解析完成标志
            if ( isValid(bf, config) ) {
                bf.setValid(true);
            }

            // 8.解析结束后
            afterAnalysis(bf, items, config);
        }

        return list;
    }

    /** 1. 将文本拆分成一条一条的格式化字符串。
     * @param rawText 原始字符串
     * @param config 运行过程中的一些基础信息和配置
     * */
    public List<String> toLines(String rawText, AnalysisConfig config) {
        String[] lines = rawText.split("\n");
        return new ArrayList<>(List.of(lines));
    }

    /** 2. 前置处理。对每一条原始字符串进行其他处理。
     * @param rawLine 原始字符串
     * @param config 运行过程中的一些基础信息和配置
     * */
    public String beforeAnalysis(String rawLine, AnalysisConfig config) {
        return rawLine;
    }

    /** 3. 将一条字符串拆分成元素数组
     * @param rawLine 一条原始字符串
     * */
    public abstract List<String> cutElements(String rawLine, AnalysisConfig config);

    /** 4.从元素数组中获取属性名称。无效数据返回 null
     * @param rawLine 一条原始字符串
     * @param items 这条原始字符串拆分的所有元素
     * @param config 运行过程中的一些基础信息和配置
     * */
    public abstract String getName(String rawLine, List<String> items, AnalysisConfig config);

    /** 5. 从元素数组中获取数据类型。无效数据返回 null
     * @param rawLine 一条原始字符串
     * @param items 这条原始字符串拆分的所有元素
     * @param config 运行过程中的一些基础信息和配置
     * */
    public abstract String getType(String rawLine, List<String> items, AnalysisConfig config);

    /** 6.从元素数组中获取注释说明
     * @param rawLine 一条原始字符串
     * @param items 这条原始字符串拆分的所有元素
     * @param config 运行过程中的一些基础信息和配置
     * */
    public abstract String getDesc(String rawLine, List<String> items, AnalysisConfig config);

    /** 7. 解析结果是否有效，根据这个结果设置最后的 valid
     * @param beanField 解析后的信息
     * @param config 运行过程中的一些基础信息和配置
     * */
    protected abstract boolean isValid(BeanField beanField, AnalysisConfig config);

    /** 8.后置处理。 BeanField 已经解析完，并且已经调用过 isValid */
    public abstract void afterAnalysis(BeanField beanField, List<String> items, AnalysisConfig config);

}
